home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / tcppack / tcppackb.lzh / src / libnetwork / gethostnamadr.c < prev    next >
C/C++ Source or Header  |  1995-11-07  |  12KB  |  560 lines

  1. /*
  2.  * gethostnamadr.c
  3.  *
  4.  * Copyright (C) 1994 First Class Technology.
  5.  */
  6.  
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9. #include<string.h>
  10. #include<errno.h>
  11.  
  12. #include"tcpipdrv.h"
  13. #include"network.h"
  14. #include"socket.h"
  15.  
  16. #define MAXHOSTADDR (15)
  17. #define MAXHOSTALIAS (15)
  18.  
  19. static struct hostent _host;
  20. static unsigned char _hostname[127 + 1];
  21. static unsigned char *h_aliases[MAXHOSTALIAS + 1];
  22. static unsigned char *h_addr_list[MAXHOSTADDR + 1];
  23.  
  24. static struct hostent *_gethostbyname (unsigned char *);
  25. static struct hostent *_gethostbyaddr (unsigned char *, int, int);
  26. static struct hostent *__gethostbyname (unsigned char *);
  27. static struct hostent *__gethostbyaddr (unsigned char *, int, int);
  28. static struct hostent * make_hostent (unsigned char *, int);
  29. static struct hostent *_copyhost (struct hostent *);
  30. static void free_hostent (void);
  31. static int add_addrs (long);
  32. static int add_aliases (unsigned char *);
  33. static unsigned short get16 (unsigned char *);
  34. static unsigned long get32 (unsigned char *);
  35. static unsigned char * get_dname (unsigned char **, unsigned char *);
  36.  
  37. _ti_func search_ti_entry (void);
  38.  
  39. /************************************************
  40.  *                        *
  41.  ************************************************/
  42. struct hostent *
  43. gethostbyname (char *name)
  44. {
  45.   struct hostent *hp;
  46.  
  47.   hp = __gethostbyname ((unsigned char *)name);
  48.   if (hp)
  49.     return hp;
  50.  
  51.   hp = _gethostbyname ((unsigned char *)name);
  52.   return _copyhost (hp);
  53. }
  54.  
  55. /************************************************
  56.  *                        *
  57.  ************************************************/
  58. struct hostent *
  59. gethostbyaddr (char *adr, int len, int type)
  60. {
  61.   struct hostent *hp;
  62.  
  63.   hp = __gethostbyaddr ((unsigned char *)adr, len, type);
  64.   if (hp)
  65.     return hp;
  66.  
  67.   hp = _gethostbyaddr ((unsigned char *)adr, len, type);
  68.   return _copyhost (hp);
  69. }
  70.  
  71. /************************************************
  72.  *                        *
  73.  ************************************************/
  74. static struct hostent *
  75. _gethostbyname (unsigned char *name)
  76. {
  77.   _ti_func func = search_ti_entry ();
  78.   if (func)
  79.     return (struct hostent *)func (_TI_gethostbyname, (long *)name);
  80.   return NULL;
  81. }
  82.  
  83. /************************************************
  84.  *                        *
  85.  ************************************************/
  86. static struct hostent *
  87. _gethostbyaddr (unsigned char *addr, int len, int type)
  88. {
  89.   _ti_func func = search_ti_entry ();
  90.   if (func)
  91.     {
  92.       long argv[3];
  93.  
  94.       argv[0] = (long)addr;
  95.       argv[1] = (long)len;
  96.       argv[2] = (long)type;
  97.  
  98.       return (struct hostent *)func (_TI_gethostbyaddr, argv);
  99.     }
  100.   return NULL;
  101. }
  102.  
  103. /************************************************
  104.  *                        *
  105.  ************************************************/
  106. static struct hostent *
  107. __gethostbyname (unsigned char *name)
  108. {
  109.   unsigned char answer[2048];
  110.   int anslen;
  111.  
  112.   anslen = res_search (name, C_IN, T_A, answer, sizeof (answer));
  113.   if (anslen > 0)
  114.     return make_hostent (answer, anslen);
  115.   else
  116.     return NULL;
  117. }
  118.  
  119. /************************************************
  120.  *                        *
  121.  ************************************************/
  122. static struct hostent *
  123. __gethostbyaddr (unsigned char *addr, int len, int type)
  124. {
  125.   unsigned char answer[2048], question[256];
  126.   int anslen, qulen;
  127.   struct hostent *tmp;
  128.  
  129.   if (type != AF_INET || len != sizeof (long))
  130.     return NULL;
  131.  
  132. #if 0    /* Inverse Query é═âLâââbâVâôâOé│éΩé╚éóé╠é┼ûΓéóìçéφé╣é≡ìsé╚éφé╚éó */
  133.   /* Inverse Query */
  134.   qulen = res_mkquery (IQUERY, NULL, C_IN, T_A, addr, sizeof (long),
  135.             NULL, question, sizeof (question));
  136.   if (qulen < 0)
  137.     return NULL;
  138.   anslen = res_send (question, qulen, answer, sizeof (answer));
  139.   tmp = make_hostent (answer, anslen);
  140.   if (tmp)
  141.     return tmp;
  142. #endif
  143.  
  144.   {
  145.     /* Query to in-addr.arpa */
  146.     unsigned char buff[64];
  147.  
  148.     sprintf (buff, "%u.%u.%u.%u.in-addr.arpa",
  149.          *(addr + 3), *(addr + 2), *(addr + 1), *addr);
  150.  
  151.     anslen = res_search (buff, C_IN, T_PTR, answer, sizeof (answer));
  152.     if (anslen > 0)
  153.       return make_hostent (answer, anslen);
  154.   }
  155.   return NULL;
  156. }
  157.  
  158. /************************************************
  159.  *                        *
  160.  ************************************************/
  161. static struct hostent *
  162. make_hostent (unsigned char *answer, int len)
  163. {
  164.   int n_q, n_a, i;
  165.   unsigned char *p;
  166.  
  167.   p = answer;
  168.   p += 4;
  169.   n_q = get16 (p); p += 2;
  170.   n_a = get16 (p); p += 6;
  171.  
  172.   if (!(n_q && n_a))
  173.     return NULL;
  174.  
  175.   _host.h_name = _hostname;
  176.   _host.h_aliases = (char **)h_aliases;
  177.   _host.h_addr_list = (char **)h_addr_list;
  178.  
  179.   free_hostent ();
  180.  
  181.   for (i = 0; i < n_q; i++)
  182.     {
  183.       int class, type;
  184.       unsigned char *dname;
  185.  
  186.       dname = get_dname (&p, answer);
  187.       type = get16 (p); p += 2;
  188.       class = get16 (p); p += 2;
  189.  
  190.       if (class == C_IN && type == T_A)
  191.     strcpy (_hostname, dname);    /* hostname or cname or inverse query*/
  192.       free (dname);
  193.     }
  194.  
  195.   for (i = 0; i < n_a; i++)
  196.     {
  197.       int class, type, ttl, length;
  198.       unsigned char *dname;
  199.  
  200.       dname = get_dname (&p, answer);
  201.  
  202.       type = get16 (p); p += 2;
  203.       class = get16 (p); p += 2;
  204.       ttl = get32 (p); p += 4;
  205.       length = get16 (p); p += 2;
  206.  
  207.       if (class == C_IN)
  208.     {
  209.       switch (type)
  210.         {
  211.         case T_A:
  212.           {
  213.         long a;
  214.  
  215.         a = get32 (p); p += 4;
  216.  
  217.         if (add_addrs (a))
  218.           {
  219.             free_hostent ();
  220.             free (dname);
  221.             return NULL;
  222.           }
  223.           }
  224.           break;
  225.         case T_PTR:
  226.           {
  227.         unsigned int num[4];
  228.         int result;
  229.         long a;
  230.  
  231.         result = sscanf (dname, "%u.%u.%u.%u.in-addr.arpa",
  232.                  num + 3, num + 2, num + 1, num);
  233.         if (result != 4)
  234.           {
  235.             free_hostent ();
  236.             free (dname);
  237.             return NULL;
  238.           }
  239.         a = (((num[0] & 0xff) << 24) + ((num[1] & 0xff) << 16)
  240.              + ((num[2] & 0xff) << 8) + (num[3] & 0xff));
  241.         if (add_addrs (a))
  242.           {
  243.             free_hostent ();
  244.             free (dname);
  245.             return NULL;
  246.           }
  247.         free (dname);
  248.         dname = get_dname (&p, answer);
  249.         strcpy (_hostname, dname);
  250.           }
  251.           break;
  252.         case T_CNAME:
  253.           if (add_aliases (dname))
  254.         {
  255.           free_hostent ();
  256.           free (dname);
  257.           return NULL;
  258.         }
  259.           free (dname);
  260.           dname = get_dname (&p, answer);
  261.           strcpy (_hostname, dname);
  262.           break;
  263.         default:
  264.           p += length;
  265.           break;
  266.         }
  267.     }
  268.       else
  269.     p += length;
  270.       free (dname);
  271.     }
  272.  
  273.   if (!*_hostname || (!*h_aliases && !*h_addr_list))
  274.     {
  275.       free_hostent ();
  276.       return NULL;
  277.     }
  278.  
  279.   return &_host;
  280. }
  281.  
  282. /************************************************
  283.  *                        *
  284.  ************************************************/
  285. static void
  286. free_hostent (void)
  287. {
  288.   unsigned char **cur;
  289.  
  290.   /* free memory that was allocated */
  291.   if (_host.h_aliases)
  292.     {
  293.       cur = (unsigned char **)_host.h_aliases;
  294.  
  295.       while (*cur)
  296.     {
  297.       free (*cur);
  298.       *cur++ = NULL;
  299.     }
  300.     }
  301.   if (_host.h_addr_list)
  302.     {
  303.       cur = (unsigned char **)_host.h_addr_list;
  304.  
  305.       while (*cur)
  306.     {
  307.       free (*cur);
  308.       *cur++ = NULL;
  309.     }
  310.     }
  311.   return;
  312. }
  313.  
  314. /************************************************
  315.  *                        *
  316.  ************************************************/
  317. static struct hostent *
  318. _copyhost (struct hostent *src)
  319. {
  320.   unsigned char **cur, *addr, *alias;
  321.   int n_addr, n_alias, addr_size, alias_size, addr_len;
  322.  
  323.   if (!src)
  324.     return NULL;
  325.  
  326.   free_hostent ();
  327.  
  328.   /* calc new alias and addrs */
  329.   n_alias = 0; alias_size = 0;
  330.   if (src->h_aliases)
  331.     {
  332.       cur = (unsigned char **)src->h_aliases;
  333.       while (*cur)
  334.     {
  335.       n_alias++;
  336.       alias_size += strlen (*cur++) + 1;
  337.     }
  338.     }
  339.   if (n_alias > MAXHOSTALIAS)
  340.     n_alias = MAXHOSTALIAS;
  341.  
  342.   n_addr = 0; addr_size = 0;
  343.   if (src->h_addr_list)
  344.     {
  345.       cur = (unsigned char **)src->h_addr_list;
  346.       while (*cur++)
  347.     n_addr++;
  348.     }
  349.   if (n_addr > MAXHOSTADDR)
  350.     n_addr = MAXHOSTADDR;
  351.   addr_len = src->h_length;
  352.   addr_size = n_addr * addr_len;
  353.  
  354.   /* malloc */
  355.   alias = malloc (alias_size);
  356.   if (!alias)
  357.     {
  358.       errno = ENOMEM;
  359.       return NULL;
  360.     }
  361.   addr = malloc (addr_size);
  362.   if (!addr)
  363.     {
  364.       free (alias);
  365.       errno = ENOMEM;
  366.       return NULL;
  367.     }
  368.  
  369.   /* make list */
  370.   {
  371.     unsigned char **p, *q;
  372.  
  373.     p = h_aliases;
  374.     q = alias;
  375.     cur = (unsigned char **)src->h_aliases;
  376.     while (*cur)
  377.       {
  378.     *p++ = q;
  379.     strcpy (q, *cur);
  380.     while (*q++)
  381.       ;
  382.     cur++;
  383.       }
  384.     *p = NULL;
  385.  
  386.     p = h_addr_list;
  387.     q = addr;
  388.     cur = (unsigned char **)src->h_addr_list;
  389.     while (*cur)
  390.       {
  391.     *p++ = q;
  392.     memcpy (q, *cur, addr_len);
  393.     q += addr_len;
  394.     cur++;
  395.       }
  396.     *p = NULL;
  397.   }
  398.   memcpy (&_host, src, sizeof (struct hostent));
  399.   strcpy (_hostname, src->h_name);
  400.   _host.h_name = _hostname;
  401.   _host.h_aliases = (char **)h_aliases;
  402.   _host.h_addr_list = (char **)h_addr_list;
  403.  
  404.   return &_host;
  405. }
  406.  
  407. /************************************************
  408.  *                        *
  409.  ************************************************/
  410. static int
  411. add_addrs (long a)
  412. {
  413.   long *q, **qq;
  414.  
  415.   q = malloc (sizeof (long));
  416.   if (!q)
  417.     return -1;
  418.   *q = a;
  419.  
  420.   /* search vector */
  421.   qq = (long **)h_addr_list;
  422.   while (*qq++)
  423.     ;
  424.   *(qq - 1) = q;
  425.  
  426.   return 0;
  427. }
  428.  
  429. /************************************************
  430.  *                        *
  431.  ************************************************/
  432. static int
  433. add_aliases (unsigned char *a)
  434. {
  435.   unsigned char *q, **qq;
  436.   int size;
  437.  
  438.   if (!a)
  439.     return 0;
  440.  
  441.   size = strlen (a);
  442.   q = malloc (size + 1);
  443.   if (!q)
  444.     return -1;
  445.   strcpy (q, a);
  446.  
  447.   /* search vector */
  448.   qq = h_aliases;
  449.   while (*qq++)
  450.     ;
  451.   *(qq - 1) = q;
  452.  
  453.   return 0;
  454. }
  455.  
  456. /************************************************
  457.  *                        *
  458.  ************************************************/
  459. static unsigned short
  460. get16 (unsigned char *p)
  461. {
  462.   unsigned short a;
  463.  
  464.   a = ((*p & 0xff) << 8) + (*(p + 1) & 0xff);
  465.  
  466.   return a;
  467. }
  468.  
  469. /************************************************
  470.  *                        *
  471.  ************************************************/
  472. static unsigned long
  473. get32 (unsigned char *p)
  474. {
  475.   unsigned long a;
  476.  
  477.   a = (((*p & 0xff) << 24) + ((*(p + 1) & 0xff) << 16)
  478.        + ((*(p + 2) & 0xff) << 8) + (*(p + 3) & 0xff));
  479.   return a;
  480. }
  481.  
  482. /************************************************
  483.  *                        *
  484.  ************************************************/
  485. static int
  486. strlen_dname (unsigned char *src, unsigned char *top)
  487. {
  488.   /* calc size */
  489.   unsigned char *q;
  490.   int size, size2;
  491.  
  492.   q = src;
  493.   size = 0;
  494.   while ((size2 = (unsigned int)(*q++ & 0xff)))
  495.     {
  496.       if ((size2 & 0xc0) == 0xc0)
  497.     {
  498.       size += strlen_dname (top + (unsigned int)*q++, top);
  499.       break;
  500.     }
  501.       else
  502.     {
  503.       size += size2 + 1;
  504.       q += size2;
  505.     }
  506.     }
  507.  
  508.   return size;
  509. }
  510.  
  511. /************************************************
  512.  *                        *
  513.  ************************************************/
  514. static unsigned char *
  515. get_dname (unsigned char **src, unsigned char *top)
  516. {
  517.   unsigned char *q, *p, *pp;
  518.   int size, size2;
  519.  
  520.   /* calc size */
  521.   size = strlen_dname (*src, top);
  522.  
  523.   pp = p = malloc (size);
  524.   if (!p)
  525.     return NULL;
  526.  
  527.   /* copy */
  528.   q = *src;
  529.   size = 0;
  530.   while ((size2 = (unsigned int)(*q++ & 0xff)))
  531.     {
  532.       if ((size2 & 0xc0) == 0xc0)
  533.     {
  534.       char *dname2;
  535.       unsigned char *tmp;
  536.  
  537.       tmp = top + *q++;
  538.       dname2 = get_dname (&tmp, top);
  539.       if (dname2)
  540.         {
  541.           strcpy (pp, dname2);
  542.           while (*pp++)
  543.         ;
  544.           free (dname2);
  545.         }
  546.       break;
  547.     }
  548.       else
  549.     {
  550.       memcpy (pp, q, size2);
  551.       pp += size2;
  552.       *pp++ = '.';
  553.       q += size2;
  554.     }
  555.     }
  556.   *(pp - 1) = '\0';
  557.   *src = q;
  558.   return p;
  559. }
  560.